package cz.muni.fi.pa165.hauntedhouses.util;

import cz.muni.fi.pa165.hauntedhouses.dto.AbilityType;
import cz.muni.fi.pa165.hauntedhouses.entity.Ability;
import cz.muni.fi.pa165.hauntedhouses.entity.Account;
import cz.muni.fi.pa165.hauntedhouses.entity.Ghost;
import cz.muni.fi.pa165.hauntedhouses.entity.House;
import cz.muni.fi.pa165.hauntedhouses.entity.Human;

/** Utility class used for validating Entities and their attributes
 *
 * @author Siliarus (Novotný Matěj 374505), Jan Vyhnanek (374138)
 */
public class Util {
    
    /**Method for validating AbilityType
     *
     * @param at AbilityType you want to validate
     * @throws IllegalArgumentException if AbilityType is null or anzhow incorrect
     */
    public static void validateAbilityType(AbilityType at){
        if (at == null) {
            throw new IllegalArgumentException("Invalid type.");
        }
        if (at.ordinal() < 0) {
            throw new IllegalArgumentException("Invalid type - ordinal < 0");
        }
    }
    
    /**Method for validating House entity
     *
     * @param house House you want to validate
     * @throws IllegalArgumentException if House or any of its attributes is null or
     * in case of strings empty
     */
    public static void validateHouse (House house){
        if (house == null) {
            throw new IllegalArgumentException("Invalid house.");
        }
        if (house.getId() != null && house.getId() < 0) {
            throw new IllegalArgumentException("Invalid id: < 0 ");
        }
        if (house.getAddress()==null || house.getAddress().length()==0) {
            throw new IllegalArgumentException("Invalid address.");
        }
        if (house.getGhostCapacity() == null || house.getGhostCapacity() < 1) {
            throw new IllegalArgumentException("Invalid ghost capacity.");
        }
        if (house.getHistory() == null || house.getHistory().length()==0) {
            throw new IllegalArgumentException("House has invalid history.");
        }
        if (house.getName()==null || house.getName().length()==0) { 
            throw new IllegalArgumentException("House has invalid name."); 
        }
        if (house.getHumanCapacity() == null || house.getHumanCapacity() <= 0) {
            throw new IllegalArgumentException("House has invalid human capacity");
        }
        if (house.getGhosts() == null) {
            throw new IllegalArgumentException("House has invalid list of Ghosts.");
        }
        if (house.getHumans() == null) {
            throw new IllegalArgumentException("House has invalid human manager");
        }
        for(Ghost ghost: house.getGhosts()){
            validateGhost(ghost);
        }
        for(Human human: house.getHumans()){
            validateHuman(human);
        }
        
    }
    
    /**Method for validating Ability entity
     *
     * @param ability Ability you want to validate
     * @throws IllegalArgumentException if Ability or any of its attributes is null or
     * in case of strings empty
     */
    public static void validateAbility (Ability ability) {
        if (ability == null) {
            throw new IllegalArgumentException("Invalid ability.");
        }
        if (ability.getId() != null && ability.getId() < 0) {
            throw new IllegalArgumentException("Invalid id: < 0 ");
        }
        if (ability.getName() == null || ability.getName().length()==0) {
            throw new IllegalArgumentException("Ability has invalid name");
        }
        if (ability.getDescription() == null || ability.getDescription().length()==0) {
            throw new IllegalArgumentException("Ability has invalid description");
        }
        if (ability.getDamage() <= 0) {
            throw new IllegalArgumentException("Ability has invalid damage");
        }
        if (ability.getAbilityLevel() <= 0 || ability.getAbilityLevel() > 3) {
            throw new IllegalArgumentException("Ability has invalid level.");
        }
    }
    
    /**Method for validating Ghost entity
     *
     * @param ghost Ghost you want to validate
     * @throws IllegalArgumentException if Ghost or any of its attributes is null or
     * in case of strings empty
     */
    public static void validateGhost (Ghost ghost) {
        if (ghost == null) {
            throw new IllegalArgumentException("Invalid ghost.");
        }
        if (ghost.getId() != null && ghost.getId() < 0) {
            throw new IllegalArgumentException("Invalid id: < 0 ");
        }
        if(ghost.getAbilities() == null) {
            throw new IllegalArgumentException("Ghost abilities are invalid");
        }
        if(ghost.getAbilityType() == null) {
            throw new IllegalArgumentException("Ghost ability type is invalid");
        }
        for (Ability a : ghost.getAbilities()) {
            validateAbility(a);
            if (a.getAbilityType() != ghost.getAbilityType()) {
                throw new IllegalArgumentException("Ghost and ability are a different type");
            }
        }
        if(ghost.getDescription() == null || ghost.getDescription().isEmpty()) {
            throw new IllegalArgumentException("Ghost description is invalid");
        }
        if(ghost.getExperience() == null || ghost.getExperience() < 0) {
            throw new IllegalArgumentException("Ghost experience is invalid");
        }
        
        if(ghost.getLastHaunted() == null) {
            throw new IllegalArgumentException("Ghost date of last haunted is invalid");
        }
        if(ghost.getLvl() == null || ghost.getLvl() <= 0 || ghost.getLvl()>9) {
            throw new IllegalArgumentException("Ghost level is invalid");
        }
        if(ghost.getName() == null || ghost.getName().isEmpty()) {
            throw new IllegalArgumentException("Ghost name is invalid");
        }
    }
    
    /**Method for validating Human entity
     *
     * @param human Human you want to validate
     * @throws IllegalArgumentException if Human or any of its attributes is null or
     * in case of strings empty
     */
    public static void validateHuman (Human human) {
        if (human == null) {
            throw new IllegalArgumentException("Invalid human.");
        }
        if (human.getId() != null && human.getId() < 0) {
            throw new IllegalArgumentException("Invalid id: < 0 ");
        }
        if (human.getDescription()== null || human.getDescription().length()==0) {
            throw new IllegalArgumentException("Human has invalid description");
        }
        if (human.getName()==null || human.getName().length()==0) {
            throw new IllegalArgumentException("Human name is invalid");
        }
        if (human.getHome()==null) {
            throw new IllegalArgumentException("Human has invalid house");
        }
        if (human.getPsyche()==null||human.getPsyche() <= 0) {
            throw new IllegalArgumentException("Human has too low health and will die immediately!");
        }
        if (human.getDescription() == null || "".equals(human.getDescription())) {
            throw new IllegalArgumentException("Human has null or empty description");
        }        
    }
    
    /**Method for validating Account entity
     *
     * @param account Account you want to validate
     * @throws IllegalArgumentException if Account or any of its attributes is null or
     * in case of strings empty
     */
    public static void validateAccount (Account account) {
        if (account == null) {
            throw new IllegalArgumentException("Invalid account.");
        }
        if (account.getId() != null && account.getId() < 0) {
            throw new IllegalArgumentException("Invalid id: < 0 ");
        }
        if (account.getUsername() == null || account.getUsername().length()==0) {
            throw new IllegalArgumentException("Account has invalid username");
        }
        if (account.getPassword() == null || account.getPassword().length()==0) {
            throw new IllegalArgumentException("Account has invalid password");
        }
        if (account.getIsAdmin() == null) {
            throw new IllegalArgumentException("Account has invalid isAdmin");
        }
    }
}
